﻿using Facebook;
using FriendAnalyzer.Infrastructure.Facebook.DataAccess;
using FriendAnalyzer.Infrastructure.Facebook.Interfaces;
using FriendAnalyzer.Infrastructure.Facebook.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Windows.Storage;

namespace FriendAnalyzer.Infrastructure.Facebook
{
    public class FacebookAuth : IFacebookAuth
    {
        private const string _redirectUrl = "http://www.facebook.com/connect/login_success.html";
        private readonly Uri _redirectUri = new Uri(_redirectUrl);
        public Uri RedirectUri
        {
            get
            {
                return _redirectUri;
            }
        }

        private string[] _permissions;
        private FacebookClient _oauth;
        private FacebookConfig _settings;

        private const string _appTokenKey = "_fbAppToken";
        private string _appToken
        {
            get
            {
                return ApplicationData.Current.LocalSettings.Values[_appTokenKey] as string;
            }
            set
            {
                ApplicationData.Current.LocalSettings.Values[_appTokenKey] = value;
            }
        }

        public FacebookAuth(string appId, string appSecret)
        {
            _settings = new FacebookConfig(appId, appSecret);
            _permissions = new[] 
            { 
                "user_about_me", 
                "offline_access", 
                "publish_stream",
                "user_events", "friends_events",
                "user_likes", "friends_likes",
                "user_groups", "friends_groups",
                "user_checkins", "friends_checkins",
            };
            _oauth = new FacebookClient 
            { 
                AppId = appId,
                AppSecret = appSecret,
            };
        }

        public Uri GetLoginUri()
        {
            var uri = new Uri(_redirectUrl);

            var parameters = GenerateLoginParameters();

            return _oauth.GetLoginUrl(parameters);
        }

        public IAuthenticationResult GetAuthenticationResult(string facebookResponse)
        {
            Uri uri;
            if (Uri.TryCreate(facebookResponse, UriKind.Absolute, out uri))
            {
                var token = _oauth.ParseOAuthCallbackUrl(uri);

                _appToken = token.AccessToken;

                return new AuthenticationResult(_settings, token);
            }
            else
            {
                return new AuthenticationResult("The incoming result was invalid.");
            }
        }

        private Dictionary<string, object> GenerateLoginParameters()
        {
            var parameters = new Dictionary<string, object>
            {
                { "client_id", _settings.ApplicationID },
                { "response_type", "token" },
                { "display", "popup" },
                { "redirect_uri", _redirectUri },
            };

            if (_permissions != null && _permissions.Any())
            {
                parameters["scope"] = string.Join(",", _permissions);
            }

            return parameters;
        }

        public async Task<IFriendsAPI> TryGetAPIAsync()
        {
            if (!string.IsNullOrEmpty(_appToken))
            {
                var client = new FacebookClient(_appToken);
                var connection = new FacebookConnection(client);

                var userRepo = new UserRepository(connection);
                var friendsRepo = new FriendRepository(connection);

                var api = new FriendsAPI(friendsRepo);

                try
                {
                    var test = await userRepo.GetUserProfile();

                    return api;
                }
                catch
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }
    }
}